#ifndef PLAYER_H
#define PLAYER_H

#include <string>
#include <vector>
#include <tuple>
#include "text_utils.h"
#include "Battle.h"
#include "Bag.h"
#include "Item.h"

using namespace std;

class Character; // 提前声明
class BackPack;
class Item;

// 状态效果类
class StatusEffect {
public:
	enum Type {
		NONE, // 无状态
		POISONED, // 中毒
		BLEEDING, // 流血
		STUNNED, // 眩晕
		STRENGTH_BOOST, // 力量提升
		DEFENSE_BOOST, // 防御提升
		SAN_LOSS,      // 理智流失（新增）
		SAN_LOCK       // 理智锁定（新增）
	};
	// 设置状态
	StatusEffect(Type type, int duration, int potency = 0)
		: type(type), duration(duration), potency(potency) {
	} // 分别是类型、持续回合数、效果强度
	Type type; // 状态类型
	int duration; // 持续时间（回合数）
	int potency; // 效果强度
};

// 技能类
class Skill {
public:
	// 设置技能
	Skill(string name, string desc, int dmg, int mana, bool offensive,
		StatusEffect::Type eff = StatusEffect::NONE, int chance = 0, int potency = 0)
		: name(name), description(desc), damage(dmg), manaCost(mana),
		isOffensive(offensive), effect(eff), effectChance(chance), effectPotency(potency) {
	} // 分别是技能名字、描述、伤害、耗蓝量、是否具有攻击性、附带状态、概率、效果强度
// 得到技能名字
	string getName() const;
	// 得到技能描述
	string getDescription() const;
	// 得到技能伤害
	int getDamage() const;
	// 得到耗蓝量
	int getManaCost() const;
	// 是否有攻击性
	bool isOffensiveSkill() const;
	// 执行技能
	void execute(Character* caster, Character* target);
	//得到技能附带的状态
	StatusEffect::Type getEffect() const {
		return effect;
	}
	//得到效果触发概率
	int getEffectChance() const {
		return effectChance;
	}
	//得到效果强度
	int getEffectPotency() const {
		return effectPotency;
	}

private:
	string name; // 技能名称
	string description; // 技能描述
	int damage; // 技能伤害
	int manaCost; // 耗蓝量
	bool isOffensive; // 是否具有攻击性
	StatusEffect::Type effect; // 技能附带的状态（眩晕、中毒等）
	int effectChance;  // 效果触发概率（百分比）
	int effectPotency; // 效果强度
};

class Character {
public:
	// 构建角色
	Character() {
		backpack = nullptr;
	}
	// 分别是名字、等级、血量、法力、力量、敏捷、防御、经验
	Character(string n, int lvl, int hp, int mp, int str, int agi, int def)
		: name(n), level(lvl), maxHealth(hp), currentHealth(hp),
		maxMana(mp), currentMana(mp), strength(str), agility(agi), defense(def) {
		backpack = nullptr;
	}
	// 析构
	virtual ~Character() {}
	// 得到角色名字
	string getName()const;
	// 得到角色等级
	int getLevel()const;
	// 得到最大生命值
	int getMaxHealth()const;
	// 得到目前生命值
	int getCurrentHealth()const;
	// 得到最大法力值
	int getMaxMana()const;
	// 得到目前法力值
	int getCurrentMana()const;
	// 得到敏捷点数
	int getAgility()const;
	// 得到力量点数
	int getStrength()const;
	// 得到幸运点数
	int getLuck()const;
	// 得到智力点数
	int getWisdom()const;
	// 得到准确度
	int getAccuracy()const;
	// 得到躲避点数
	int getDodging()const;
	// 得到防御点数
	int getDefense()const;
	// 展示属性，NPC与Charles有不同
	virtual void showInfo()const;
	// 得到技能名称
	vector<Skill>& getSkills();
	// 是否存活
	bool isAlive() const;
	// 减少生命值
	void takeDamage(int damage);
	// 恢复生命值
	void heal(int amount);
	// 恢复法力值
	void restoreMana(int amount);
	// 添加状态效果
	void addStatusEffect(StatusEffect effect);
	// 描述状态效果
	void describeStatusEffect(StatusEffect effect, bool isAdded);
	// 检查是否有特定状态
	bool hasStatusEffect(StatusEffect::Type type) const;
	// 处理每回合的状态效果
	bool processStatusEffects();
	// 计算修正后的力量属性
	int getEffectiveStrength()const;
	// 计算修正后的防御属性
	int getEffectiveDefense() const;
	// 显示状态
	void displayStatus() const;
	// 攻击目标
	virtual void attack(Character* target);
	// 选择行动（玩家和怪物有不同实现）
	virtual void chooseAction(Character* target);

	// 新增：获取状态效果（const版本）
	const std::vector<StatusEffect>& getStatusEffects() const {
		return statusEffects;
	}

	// 新增：非const版本（如需修改时使用）
	std::vector<StatusEffect>& getStatusEffects() {
		return statusEffects;
	}

	// 修正：添加const限定符，返回const引用
	const std::vector<Skill>& getSkills() const {
		return skills;
	}

	// 新增：设置名字的方法
	void setName(const std::string& n) {
		name = n;
	}

	// 添加setBackpack函数：设置背包
	void setBackpack(BackPack* backpack);

	// 添加getBackpack函数
	BackPack* getBackpack();


protected:
	int maxHealth = 0; // 最大生命值
	int currentHealth = 0; // 当前生命值
	int maxMana = 0; // 最大法力值
	int currentMana = 0; // 当前法力值
	int defense = 0;//防御
	int agility = 0; // 敏捷
	int strength = 0; // 力量
	int luck = 0; // 幸运
	int wisdom = 0; // 智力
	int level = 1; // 等级
	int accuracy = 0; // 准确度
	int dodging = 0; // 躲避
	string name; // 角色名字
	vector<Skill> skills; // 技能
	vector<StatusEffect> statusEffects; // 负面效果
	BackPack* backpack;  // 背包
};

class Player :public Character {
public:
	Player() {}
	// 新增：带理智值初始化的构造函数
	Player(string n, int lvl, int hp, int mp, int str, int agi, int def) :
		Character(n, lvl, hp, mp, str, agi, def),
		maxSan(100), san(100), sanSpeed(5) {
	}

	// 设置技能
	// 分别代表技能名称、技能描述、技能伤害、技能耗蓝量、
	// 技能是否有伤害、技能产生效果、技能成功概率、技能持续回合
	void setSkills(string name, string desc, int dmg, int mana,
		bool offensive, StatusEffect::Type type, int probability, int duration);
	// 分配Charles属性
	void distribute();
	// 教皇（友人）提供buff
	void buff();
	// 教皇（友人）buff消失
	void withoutBuff();
	// 展示背包
	void showBag();
	// 展示Charles属性
	void showInfo()const;
	//设置生命点数
	void setMaxHealth(int health); // health是所加的生命点数
	// 设置法力点数
	void setMaxMana(int mana); // mana是所加的法力点数
	// 设置防御点数
	void setDefense(int defense); // defense是所加的防御点数
	// 设置幸运点数
	void setLuck(int luck); // luck是所加的幸运点数
	// 设置敏捷点数
	void setAgility(int agi); // agi是所加的敏捷点数
	// 设置力量点数
	void setStrength(int str); // str是所加的力量点数
	// 设置智力点数
	void setWisdom(int wis); // wis是所加的智力点数
	// 设置准确度点数
	void setAccuracy(int acc); // acc是所加的准确度点数
	// 设置躲避点数
	void setDodging(int dod); // dod是所加的躲避点数
	// 得到经验值
	int getExpoints()const;
	// 设置Charles经验
	void setExpoints(int exp); // exp是经验值，输入得到的经验即可，自动升级
	// 得到金钱数
	int getMoney()const;
	// 花费金钱数目
	void PayMoney(int money); // money是金钱额
	// 赚取金钱
	void EarnMoney(int money); // money是金钱额
	// 得到复活次数
	int getReamount()const;
	// 增加复活次数
	void setReamount();

	// 【完善理智系统】
	// 得到当前san值
	double getSan()const;
	// 得到最大san值
	double getMaxSan()const;  // 新增
	// 恢复san值
	void restoreSan(double amount);  // 新增：更语义化的恢复方法
	// 受到理智伤害
	void takeSanDamage(double amount);  // 新增：更语义化的伤害方法
	// 直接设置san值（带边界检查）
	void setSan(double san);
	// 得到san值掉落速率
	double getSanSpeed()const;
	// 更改san值掉落速率，>1 加速掉落，<1 掉落减速
	void setSanSpeed(double sp); // sp的值要合理，尽量在1左右
	// 增加最大san值
	void increaseMaxSan(double amount);  // 新增：支持最大理智提升

	// 选择行动
	void chooseAction(Character* target)override;
	// 复活
	void Respawn(int backupLife, int backupMana); // backupLife是战斗前的生命值，backupMana是战斗前的法力值

	// 获取物品列表
	const std::vector<Item>& getInventory() const;

	// 检查物品列表是否为空
	bool isInventoryEmpty() const;

	// 获取物品总数
	size_t getInventorySize() const;

private:
	int money = 100; // 金钱
	int reamount = 0; // 重生次数
	double maxSan;    // 新增：最大理智值
	double san;       // 当前理智值
	double sanSpeed;  // san掉落速率
	int expoints = 0;
};//所有的属性升级可获得的满点都是50，生命值是500，装上装备后满点估计到100，生命1000


class Monster : public Character {
public:
	// 创建敌人
	Monster(string name, int level, int hp, int mp, int str, int agi, int def, int exp) // 分别是名字、等级、血量、法力、力量、敏捷、防御、击败后得到的经验
		: Character(name, level, hp, mp, str, agi, def), expReward(exp) {
	}
	// 得到击败后获得的经验
	int getExpReward()const;
	// 怪物战斗选择
	void chooseAction(Character* target) override;
	// 随机创建小怪
	Monster createRandomMonster(int level); // level是玩家的等级

private:
	int expReward = 0;
};

#endif // PLAYER_H
